package com.sihai.core.web.struts2;

import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.struts2.ServletActionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.opensymphony.xwork2.ActionContext;

/**
 * <code>BaseAction</code>是xwork <code>ActionSupport</code>扩展,提供一些方便的方法<br>
 */
public class BaseAction extends PageSupportAction {

	private static final long serialVersionUID = -2881986774966070834L;

	/**
	 * Logger for this class
	 */
	protected Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * 直接得到request.getParameter(name)的值<br>
	 * 需要应用服务器运行时支持
	 *
	 * @param name name
	 * @return value
	 */
	public String getParameter(String name) {
		return ServletActionContext.getRequest().getParameter(name);
	}

	public Long getLongParameter(String parameterName, boolean failIfNotFound) {
		String value = getParameter(parameterName);
		if (failIfNotFound) {
			Validate.notEmpty(value, "must set paramter:" + parameterName);
		}

		if (!StringUtils.isNumeric(value)) {
			throw new IllegalArgumentException("parameter " + parameterName + "'s value is not a numeric value");
		}
		return Long.valueOf(value);
	}

	/**
	 * 直接得到request.getParameterValues(name)的值<br>
	 * 需要应用服务器运行时支持
	 *
	 * @param name name
	 * @return values
	 */
	public String[] getParameterValues(String name) {
		return ServletActionContext.getRequest().getParameterValues(name);
	}

	/**
	 * @return Params
	 */
	public Params getParams() {
		return new Params(ServletActionContext.getRequest());
	}

	/**
	 * 某些情况下需要传递参数到action，但action对这些参数不感兴趣，可能只是将这些参数导向到相关的view
	 * <p/>
	 * usage:<br>
	 * if the get url is:http://localhost:8080/Base.action?id=1&name=2<br>
	 * you can access the id and name variable in the view like below:<br>
	 * ${params.id},${params.name}<br>
	 *
	 * @author snowway
	 */
	@SuppressWarnings("rawtypes")
	public static class Params extends HashMap {
		/**
         *
         */
		private static final long serialVersionUID = 6124274561487102384L;

		private HttpServletRequest request;

		public Params(HttpServletRequest request) {
			this.request = request;
		}

		public String get(Object key) {
			if (this.request != null)
				return request.getParameter(key.toString());
			throw new IllegalStateException("can not invoke in non web environment!");
		}

	}

	protected String namespace;

	protected String action;

	protected String method;

	public String getNamespace() {
		if (StringUtils.isBlank(this.namespace)) {
			this.namespace = ActionContext.getContext().getActionInvocation().getProxy().getNamespace();
		}
		return this.namespace;

	}

	public String getAction() {
		if (StringUtils.isBlank(this.action)) {
			this.action = ActionContext.getContext().getActionInvocation().getProxy().getActionName();
		}
		return this.action;
	}

	public String getMethod() {
		if (StringUtils.isBlank(this.method)) {
			this.method = ActionContext.getContext().getActionInvocation().getProxy().getMethod();
		}
		return this.method;
	}

	protected String redirect(String method) {
		return this.redirect(this.getAction(), method);
	}

	protected String redirect(String action, String method) {
		return this.redirect(this.getNamespace(), action, method);
	}

	protected String redirect(String namespace, String action, String method) {
		this.namespace = namespace;
		this.action = action;
		this.method = method;
		return "redirect";
	}

	protected String chain(String action, String method) {
		return this.chain(this.getNamespace(), action, method);
	}

	protected String chain(String namespace, String action, String method) {
		this.namespace = namespace;
		this.action = action;
		this.method = method;
		return "chain";
	}

	private String directToUri;

	public String getDirectToUri() {
		return this.directToUri;
	}

	protected String toUrl(String uri) {
		this.directToUri = uri;
		return "directTo";
	}

	private String pageUrl;

	public String getPageUrl() {
		return pageUrl;
	}

	public void setPageUrl(String pageUrl) {
		this.pageUrl = pageUrl;
	}

}
